﻿using System.Text;
using System.Text.Json;

namespace 中间件测试
{
    public class RequestCheckMiddleware
    {
        private readonly RequestDelegate _next;
        public RequestCheckMiddleware(RequestDelegate next)
        {
            _next= next;
        }
        public async Task InvokeAsync(HttpContext context)
        {
            HttpRequest request = context.Request;
            //缓存下来允许多次读取
            request.EnableBuffering();
            var reader = new StreamReader(request.Body, Encoding.UTF8);
            string data = await reader.ReadToEndAsync();
            // 重置流的位置以便后续中间件可以读取  
            request.Body.Position = 0;
            try
            {
                var inputJson = JsonSerializer.Deserialize<BaseRequest>(data);
                // 假设 BaseRequest.TimeSpan 是一个 long 类型的 UNIX 时间戳  
                if (string.IsNullOrEmpty(inputJson.TimeSpan))
                {
                    await HandleError(context, 500, "时间戳为空！");
                    return;
                }

                var requestTime = UnixTimeStampToDateTime(Convert.ToInt64(inputJson.TimeSpan));
                if (DateTime.Now - requestTime > TimeSpan.FromMinutes(2))
                {
                    await HandleError(context, 429, "超时请求！");
                    return;
                }
                await _next(context);
            }
            catch (Exception ex)
            {
                await HandleError(context, 400, $"处理请求失败: {ex.Message}");
            }
        }
        private async Task HandleError(HttpContext context, int statusCode, string message)
        {
            context.Response.StatusCode = statusCode;
            var result = new { code = statusCode, message = message, result = new object() };
            await context.Response.WriteAsync(JsonSerializer.Serialize(result));
        }

        private DateTime UnixTimeStampToDateTime(long unixTimeStamp)
        {
            // UNIX 时间戳转换为 DateTime  
            DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            dateTime = dateTime.AddSeconds(unixTimeStamp).ToLocalTime();
            return dateTime;
        }
    }
    public class BaseRequest
    {
        public string TimeSpan { get; set; }
    }
}
